package mj.ocraptor.javafx.controllers; import java.util.ArrayList; import java.util.List; import javafx.application.Platform; import javafx.collections.ObservableList; import javafx.concurrent.Task; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Cursor; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.ComboBox; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; import javafx.scene.control.TextField; import javafx.scene.control.ToggleButton; import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.scene.paint.Color; import javafx.scene.paint.Paint; import javafx.scene.shape.Line; import javafx.scene.text.Text; import mj.ocraptor.configuration.Config; import mj.ocraptor.configuration.Localization; import mj.ocraptor.configuration.properties.ConfigBool; import mj.ocraptor.configuration.properties.ConfigInteger; import mj.ocraptor.configuration.properties.ConfigString; import mj.ocraptor.console.Platform.Os; import mj.ocraptor.javafx.GUITemplate; import mj.ocraptor.javafx.Icon; import mj.ocraptor.javafx.Theme; import mj.ocraptor.tools.SystemTools; import mj.ocraptor.tools.St; import mj.ocraptor.tools.Tp; import org.apache.commons.collections4.BidiMap; import org.apache.commons.lang3.LocaleUtils; public class SettingsManager extends GUITemplate { private static final org.slf4j.Logger LOGGER = org.slf4j.LoggerFactory .getLogger(SettingsManager.class); // *INDENT-OFF* public static double INIT_WIDTH = 550; public static double INIT_HEIGHT = 400; public static final String FXML = "SettingsManager.fxml"; private static final String SAVED_STYLE_CLASS = "settingsButtonSaved", SETTINGS_TITLE_CLASS = "settingsTitle", SETTINGS_DIVIDER_CLASS = "settingsManagerDivider", SETTINGS_BUTTON_DEFAULT_CLASS = "settingsButtonDefault"; // *INDENT-ON* private boolean breakSaving = false; private ObservableList<Node> children; private int handlerCount; private String originalTheme; private Config config; private List<EventHandler<ActionEvent>> saveHandlers; private List<ToggleButton> fileTypeButtons; private boolean fileButtonsToggled = true; @FXML private Button cancel; @FXML private VBox hboxContainer; @FXML private Button saveButton; @FXML private ToggleButton settingsButton; @FXML private Label feedbackMessage; @FXML private ScrollPane settingsScrollPane; // ------------------------------------------------ // // -- // ------------------------------------------------ // @FXML void saveButtonClicked(ActionEvent event) { this.breakSaving = false; for (EventHandler<ActionEvent> handler : this.saveHandlers) { handler.handle(null); if (this.breakSaving) { break; } } if (!this.breakSaving) { this.g.getParentController().initMultiCoreProcessing(); this.feedbackMessage.setText(g.getText("SETTINGS.SAVED")); final ObservableList<String> styleClasses = this.feedbackMessage.getStyleClass(); styleClasses.clear(); styleClasses.add(SAVED_STYLE_CLASS); } String newTheme = this.cfg.getProp(this.cfg.getConfigMasterFilePath(), ConfigString.THEME); if (!newTheme.equals(originalTheme)) { this.changeThemeTo(Theme.getByName(newTheme)); this.originalTheme = newTheme; } this.executeWorker(saveWorker()); } @FXML void cancelButtonClicked(ActionEvent event) { this.gotoPage(EditDatabase.FXML, EditDatabase.INIT_WIDTH, EditDatabase.INIT_HEIGHT); } @FXML void settingsButtonClicked(ActionEvent event) { Platform.runLater(new Runnable() { @Override public void run() { outTransition(); } }); this.executeWorker(changeSettingsWorker()); } // ------------------------------------------------ // // -- // ------------------------------------------------ // @Override protected void initVisibility() { this.helpButton.setDisable(false); } @Override protected void initLabels() { this.feedbackMessage.setText(g.getText("SETTINGS.SAVE_REMINDER")); // TODO: style this.feedbackMessage.setTextFill(Color.GRAY); this.settingsButton.setText(g.getText("SETTINGS.MORE_BUTTON")); this.title.setText(g.getText("SETTINGS.TITLE")); this.cancel.setText(g.getText("BACK_BUTTON")); this.saveButton.setText(g.getText("SAVE")); this.helpButton.setText(g.getText("HELP")); this.addImageIcon(this.settingsButton, Icon.LIST, 0); } @Override public void initCustomComponents() { this.fileTypeButtons = new ArrayList<ToggleButton>(); this.saveHandlers = new ArrayList<EventHandler<ActionEvent>>(); this.children = this.hboxContainer.getChildren(); this.config = Config.inst(); this.updateFields(); this.addStandardSettings(); this.originalTheme = this.cfg.getProp(this.cfg.getConfigMasterFilePath(), ConfigString.THEME); this.pane.getScene().addEventHandler(KeyEvent.ANY, new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { if (event.getCode() == KeyCode.ENTER) { // } if (event.getCode() == KeyCode.ESCAPE) { cancelButtonClicked(null); } } }); } private Task<Object> changeSettingsWorker() { return new Task<Object>() { @Override protected Object call() throws Exception { Thread.sleep(500); Platform.runLater(new Runnable() { @Override public void run() { if (settingsButton.isSelected()) { addImageIcon(settingsButton, Icon.LIST_WHITE, 0); settingsButton.setText(g.getText("SETTINGS.LESS_BUTTON")); addAdvancedSettings(); } else { while (children.size() > handlerCount) { children.remove(children.size() - 1); } while (saveHandlers.size() > handlerCount) { saveHandlers.remove(saveHandlers.size() - 1); } settingsButton.setText(g.getText("SETTINGS.MORE_BUTTON")); addImageIcon(settingsButton, Icon.LIST, 0); } inTransitionAsWorker(500); } }); return true; } }; } /** * * */ private void addStandardSettings() { try { // ------------------------------------------------ // this.addTitle(g.getText("SETTINGS.TITLE_DETAILS", Config.HARDCODED_VERSION)); this.addBooleanButton(g.getText("SETTINGS.ENABLE_OCR"), null, ConfigBool.ENABLE_IMAGE_OCR, false, false).getKey(); // TODO: new feature // this.addBooleanButton(g.getText("SETTINGS.INCLUDE_FULLTEXT"), null, // ConfigBool.INCLUDE_FULLTEXT, // false, false).getKey(); this.addBooleanButton(g.getText("SETTINGS.INCLUDE_METADATA"), null, ConfigBool.INCLUDE_METADATA, false, false).getKey(); // ------------------------------------------------ // // TODO: Metadata button // this.addBooleanButton(g.getText("SETTINGS.ENABLE_METADATA"), null, // ConfigBool.INCLUDE_METADATA, // true, false).getKey(); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.FILETYPES_TO_INCLUDE")); // ------------------------------------------------ // this.addToggleAllButton(null, true); // ------------------------------------------------ // Tp<EventHandler<ActionEvent>, ToggleButton> filetypeButton; filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_IMAGE_FILES"), Icon.IMAGE, null, ConfigBool.INCLUDE_STANDALONE_IMAGE_FILES, false, false); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_PDF"), Icon.PDF, null, ConfigBool.INCLUDE_PDF_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_PS"), Icon.PS, null, ConfigBool.INCLUDE_POSTSCRIPT_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_EPUB"), Icon.RTF, null, ConfigBool.INCLUDE_EPUB_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_XOURNAL"), Icon.ADDON, null, ConfigBool.INCLUDE_XOURNAL_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_XML"), Icon.TEXT, null, ConfigBool.INCLUDE_XML_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_HTML"), Icon.TEXT, g .getText("SETTINGS.HTML_INFO"), ConfigBool.INCLUDE_HTML_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_TEXT"), Icon.TEXT, null, ConfigBool.INCLUDE_TEXT_FILES, false, false); this.fileTypeButtons.add(filetypeButton.getValue()); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.MS_OFFICE")); // ------------------------------------------------ // filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_WORD"), Icon.DOCX, null, ConfigBool.INCLUDE_MS_WORD_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_EXCEL"), Icon.XLSX, null, ConfigBool.INCLUDE_MS_EXCEL_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_PPT"), Icon.PPTX, null, ConfigBool.INCLUDE_MS_POWERPOINT_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_XPS"), Icon.XPS, null, ConfigBool.INCLUDE_MS_XPS_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_RTF"), Icon.RTF, g .getText("SETTINGS.OCR_NOT_SUPPORTED"), ConfigBool.INCLUDE_MS_RTF_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.INCLUDE_LIBRE")); // ------------------------------------------------ // filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_WRITER"), Icon.ODT, null, ConfigBool.INCLUDE_LO_WRITER_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_IMPRESS"), Icon.ODP, null, ConfigBool.INCLUDE_LO_IMPRESS_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_CALC"), Icon.ODS, null, ConfigBool.INCLUDE_LO_CALC_FILES, false, true); this.fileTypeButtons.add(filetypeButton.getValue()); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.UPCOMING_FILETYPES")); // ------------------------------------------------ // // ------------------------------------------------ // // ------------------------------------------------ // // this.addSeperator(); // this.addTitle(g.getText("SETTINGS.IWORK9")); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_PAGES"), Icon.ADDON, this.g.getText("SETTINGS.APPLE_WORK13_NOT_SUPPORTED"), ConfigBool.INCLUDE_APPLE_PAGES_FILES, true, true); // this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_NUMBERS"), Icon.ADDON, null, ConfigBool.INCLUDE_APPLE_NUMBERS_FILES, true, true); // this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_KEY"), Icon.ADDON, null, ConfigBool.INCLUDE_APPLE_KEY_FILES, true, true); // this.fileTypeButtons.add(filetypeButton.getValue()); final String notSupported = g.getText("SETTINGS.FILETYPE_NOT_SUPPORTED"); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_ARCHIVES"), Icon.ADDON, notSupported, ConfigBool.INCLUDE_ARCHIVES, true, true); // this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_DJVU"), Icon.ADDON, notSupported, ConfigBool.INCLUDE_DJVU_FILES, true, true); // this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_PUBLISHER"), Icon.ADDON, notSupported, ConfigBool.INCLUDE_MS_PUBLISHER_FILES, true, true); // this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_ONENOTE"), Icon.ADDON, notSupported, ConfigBool.INCLUDE_MS_ONENOTE_FILES, true, true); // this.fileTypeButtons.add(filetypeButton.getValue()); filetypeButton = this.addBooleanButton(g.getText("SETTINGS.INCLUDE_EMAILS"), Icon.ADDON, notSupported, ConfigBool.INCLUDE_EMAIL_FILES, true, true); // this.fileTypeButtons.add(filetypeButton.getValue()); // ------------------------------------------------ // this.handlerCount = this.children.size(); } catch (NullPointerException e) { // TODO: logging e.printStackTrace(); } } /** * * */ private void addAdvancedSettings() { try { this.addCustomDivider(); // ------------------------------------------------ // this.addTitle(g.getText("SETTINGS.OCR_SECTION")); // ------------------------------------------------ // this.addBooleanButton(g.getText("SETTINGS.INCLUDE_PREPROCESS_IMAGE"), null, ConfigBool.PRE_PROCESS_IMAGES_FOR_OCR, false, false).getKey(); // ------------------------------------------------ // // this.addIntegerField(ConfigInteger.MAX_FULLTEXT_LENGTH, null, g // .getText("SETTINGS.MAX_FULLTEXT_LENGTH"), null, false, ""); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.MIN_IMAGE_SIZE_IN_KB, null, g .getText("SETTINGS.MIN_IMAGE_SIZE"), null, false, "KB"); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.MAX_IMAGE_SIZE_IN_KB, null, g .getText("SETTINGS.MAX_IMAGE_SIZE"), null, false, "KB"); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.MIN_IMAGE_WIDTH_FOR_OCR, null, g .getText("SETTINGS.MIN_IMAGE_WIDTH"), null, false, "Px"); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.MAX_IMAGE_WIDTH_FOR_OCR, null, g .getText("SETTINGS.MAX_IMAGE_WIDTH"), null, false, "Px"); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.MIN_IMAGE_HEIGHT_FOR_OCR, null, g .getText("SETTINGS.MIN_IMAGE_HEIGHT"), null, false, "Px"); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.MAX_IMAGE_HEIGHT_FOR_OCR, null, g .getText("SETTINGS.MAX_IMAGE_HEIGHT"), null, false, "Px"); // ------------------------------------------------ // String langInfo = g.getText("SETTINGS.CURRENTLY_INSTALLED") + "\n"; List<String> languageStrings = Config.getLanguageStrings(); if (languageStrings != null && !languageStrings.isEmpty()) { for (String lang : languageStrings) { langInfo += lang + ", "; } langInfo = St.removeLastCharacters(langInfo, 2); } this.addStringField(g.getText("SETTINGS.OCR_LANG"), langInfo, ConfigString.DEFAULT_LANGUAGE_FOR_OCR, false); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.ERROR_HANDLING")); // ------------------------------------------------ // this.saveHandlers.add(this.addBooleanButton(g.getText("SETTINGS.BUG_REPORTS"), null, ConfigBool.ENABLE_BUG_REPORT_SCREENS, false, false).getKey()); // ------------------------------------------------ // this.saveHandlers.add(this.addBooleanButton(g.getText("SETTINGS.PAUSE_INDEXING_ON_ERROR"), null, ConfigBool.PAUSE_ON_ERROR, false, false).getKey()); // ------------------------------------------------ // this.saveHandlers.add(this.addBooleanButton(g.getText("SETTINGS.APP_STD_ERR"), null, ConfigBool.ENABLE_USER_COMMAND_STDERR, false, false).getKey()); // ------------------------------------------------ // this.saveHandlers.add(this.addDropdownMenu(this.cfg.getConfigUserFilePath(), g .getText("SETTINGS.LOGGER_LEVEL"), null, ConfigString.LOGFILE_THRESHOLD_OUTPUT, new String[] { "FATAL", "ERROR", "INFO" }, 110, true)); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.INDEXING")); // ------------------------------------------------ // this.saveHandlers.add(this.addBooleanButton(g.getText("SETTINGS.SHOW_ONLY_NEW"), null, ConfigBool.NEW_FILES_NOTIFICATION_ONLY, false, false).getKey()); // ------------------------------------------------ // this.saveHandlers.add(this.addBooleanButton(g.getText("SETTINGS.REMOVE_MISSING_FILES"), null, ConfigBool.ALWAYS_REMOVE_MISSING_FILES_FROM_DB, false, false).getKey()); // ------------------------------------------------ // this.saveHandlers.add(this.addBooleanButton(g.getText("SETTINGS.INCLUDE_HIDDEN_FOLDERS"), null, ConfigBool.INDEX_HIDDEN_FILES_AND_FOLDERS, false, true).getKey()); // ------------------------------------------------ // int availableCores = Runtime.getRuntime().availableProcessors(); if (availableCores > 1) { Integer[] cores = new Integer[availableCores + 1]; for (int i = 0; i <= availableCores; i++) cores[i] = i; this.saveHandlers.add(this.addDropdownMenu(null, null, g.getText("SETTINGS.CPU_CORES"), ConfigInteger.NUMBER_OF_CPU_CORES_TO_USE, cores, 75, false)); } // ------------------------------------------------ // this.addIntegerField(ConfigInteger.RMI_SERVER_PORT, null, g.getText("SETTINGS.RMI_PORT"), null, true, ""); // ------------------------------------------------ // Tp<EventHandler<ActionEvent>, TextField> xms = this.addIntegerField( ConfigInteger.PROCESS_XMS, null, g.getText("SETTINGS.PROCESS_XMS"), null, true, "MB"); Tp<EventHandler<ActionEvent>, TextField> xmx = this.addIntegerField( ConfigInteger.PROCESS_XMX, null, g.getText("SETTINGS.PROCESS_XMX"), null, true, "MB"); this.saveHandlers.remove(xmx.getKey()); this.saveHandlers.remove(xms.getKey()); EventHandler<ActionEvent> memoryHandler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { try { Integer xmsValue = St.extractInteger(xms.getValue().getText()); Integer xmxValue = St.extractInteger(xmx.getValue().getText()); final SystemTools sigar = new SystemTools(); long maxRam = sigar.getMaxRamInMB(); maxRam -= 1024; // remove an estimated value for os memory // allocation if (xmsValue < 64) { // lower end feedbackMessage.setText(g.getText("SETTINGS.XMS_TOO_LOW")); breakSaving = true; } if (xmsValue > xmxValue) { feedbackMessage.setText(g.getText("SETTINGS.XMS_TOO_HIGH")); breakSaving = true; } if (xmxValue > maxRam) { feedbackMessage.setText(g.getText("SETTINGS.XMX_TOO_HIGH")); breakSaving = true; } } catch (Exception e) { } } }; this.saveHandlers.add(memoryHandler); this.saveHandlers.add(xmx.getKey()); this.saveHandlers.add(xms.getKey()); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.PROCESSING_TIMEOUT_IN_SECONDS, null, "Timeout", null, true, " s"); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.MAX_TEXT_SIZE_IN_KB, null, g .getText("SETTINGS.MAX_TEXT_FILE_SIZE"), null, true, "KB"); // ------------------------------------------------ // this.addStringField(g.getText("SETTINGS.TEXT_FILE_EXT"), null, ConfigString.TEXT_FILE_EXTENSIONS, false); // ------------------------------------------------ // this.addStringField(g.getText("SETTINGS.PASSWORDS"), g.getText("SETTINGS.PLANNED_INFO"), ConfigString.PASSWORDS_TO_USE, false); // ------------------------------------------------ // this.addStringField(g.getText("SETTINGS.IGNORING"), g.getText("SETTINGS.PLANNED_INFO"), ConfigString.FILES_AND_DIRS_TO_IGNORE, false); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.SEARCHING")); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.DIALOG_SNIPPET_MAX_STRING_LENGTH, null, g .getText("SETTINGS.FULLTEXT_SNIPPET_LENGTH"), null, true, ""); // ------------------------------------------------ // this.addIntegerField(ConfigInteger.MAX_SEARCH_RESULTS, null, g .getText("SETTINGS.MAX_SEARCH_RESULTS"), null, false, ""); // ------------------------------------------------ // this.addBooleanButton(g.getText("SETTINGS.ENABLE_ENTRY_DELETION_BY_USER"), null, ConfigBool.ENABLE_ENTRY_DELETION_BY_USER, false, false).getKey(); // ------------------------------------------------ // this.addStringField(g.getText("SETTINGS.STOPWORDS"), null, ConfigString.STOP_WORDS, true); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.GLOBAL")); // ------------------------------------------------ // this.saveHandlers.add(this.addDropdownMenu(this.cfg.getConfigMasterFilePath(), g .getText("SETTINGS.DEFAULT_LANGUAGE"), null, ConfigString.DEFAULT_LOCALE, this.cfg .getProp(ConfigString.AVAILABLE_LOCALES).split(";"), 200, true)); // ------------------------------------------------ // this.saveHandlers.add(this.addDropdownMenu(this.cfg.getConfigMasterFilePath(), g .getText("SETTINGS.DEFAULT_THEME"), null, ConfigString.THEME, Theme.valuesAsString(), 200, true)); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.BASH_COMMAND")); // ------------------------------------------------ // ConfigString cmd = ConfigString.getByOs(ConfigString.DIRECTORY_OPEN_CMD_); Tp<EventHandler<ActionEvent>, TextField> app = this.addStringField(g.getText("DIRECTORY"), null, cmd, false); EventHandler<ActionEvent> dirHandler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { String text = app.getValue().getText().trim(); feedbackMessage.setTextFill(Color.DARKRED); if (!text.isEmpty()) { if (!(text.contains("{0}") || text.contains("{1}"))) { feedbackMessage.setText(g.getText("SETTINGS.NOT_A_VALID_DIR_COMMAND")); breakSaving = true; } } if (!breakSaving) { cfg.setProp(cmd, text); } } }; // overwrite standard event handler this.saveHandlers.remove(app.getKey()); this.saveHandlers.add(dirHandler); // ------------------------------------------------ // this.addCMDField(ConfigString.getByOs(ConfigString.IMAGE_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.IMAGE"), false); this.addCMDField(ConfigString.getByOs(ConfigString.TEXT_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.TEXT"), true); this.addCMDField(ConfigString.getByOs(ConfigString.EPUB_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.EPUB"), true); this.addCMDField(ConfigString.getByOs(ConfigString.PDF_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.PDF"), true); this.addCMDField(ConfigString.getByOs(ConfigString.PS_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.PS"), true); this.addCMDField(ConfigString.getByOs(ConfigString.XOJ_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.XOURNAL"), true); this.addCMDField(ConfigString.getByOs(ConfigString.HTML_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.HTML"), true); this.addCMDField(ConfigString.getByOs(ConfigString.XML_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.XML"), true); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.MS_OFFICE")); // ------------------------------------------------ // this.addCMDField(ConfigString.getByOs(ConfigString.MS_WORD_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.WORD"), true); this.addCMDField(ConfigString.getByOs(ConfigString.MS_EXCEL_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.EXCEL"), true); this.addCMDField(ConfigString.getByOs(ConfigString.MS_PPT_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.PPT"), true); this.addCMDField(ConfigString.getByOs(ConfigString.MS_XPS_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.XPS"), true); this.addCMDField(ConfigString.getByOs(ConfigString.MS_RTF_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.RTF"), true); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.INCLUDE_LIBRE")); // ------------------------------------------------ // this.addCMDField(ConfigString.getByOs(ConfigString.LO_WRITER_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.WRITER"), true); this.addCMDField(ConfigString.getByOs(ConfigString.LO_CALC_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.CALC"), true); this.addCMDField(ConfigString.getByOs(ConfigString.LO_IMPRESS_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.IMPRESS"), true); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.IWORK")); // ------------------------------------------------ // this.addCMDField(ConfigString.getByOs(ConfigString.APPLE_PAGES_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.PAGES"), true); this.addCMDField(ConfigString.getByOs(ConfigString.APPLE_NUMBERS_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.NUMBERS"), true); this.addCMDField(ConfigString.getByOs(ConfigString.APPLE_KEY_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.KEY"), true); // ------------------------------------------------ // this.addSeperator(); this.addTitle(g.getText("SETTINGS.NOT_SUPPORTED")); // ------------------------------------------------ // this.addCMDField(ConfigString.getByOs(ConfigString.DJVU_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.DJVU"), true); this.addCMDField(ConfigString.getByOs(ConfigString.ARCHIVE_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.ARCHIVE"), true); this.addCMDField(ConfigString.getByOs(ConfigString.MS_PUB_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.PUBLISHER"), true); this.addCMDField(ConfigString.getByOs(ConfigString.MS_ONE_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.ONENOTE"), true); this.addCMDField(ConfigString.getByOs(ConfigString.EMAIL_FILE_OPEN_CMD_), // null, g.getText("SETTINGS.EMAIL"), true); // ------------------------------------------------ // } catch (NullPointerException e) { LOGGER.error("Can not generate all setting entries", e); gotoPage(EditDatabase.FXML, EditDatabase.INIT_WIDTH, EditDatabase.INIT_HEIGHT); } } /** * * */ private void addSeperator() { this.addTitle(""); } /** * * * @param titleText */ private void addTitle(String titleText) { final Text description = new Text(titleText); final ObservableList<String> styleClasses = description.getStyleClass(); styleClasses.clear(); styleClasses.add(SETTINGS_TITLE_CLASS); this.children.add(description); } /** * * * @param cmd * @param appString */ private void addCMDField(ConfigString cmd, String infoString, String appString, boolean helpDisabled) { Tp<EventHandler<ActionEvent>, TextField> app = this.addStringField(appString, infoString, cmd, helpDisabled); this.saveHandlers.remove(app.getKey()); this.saveHandlers.add(this.addDefaultAppEventHandler(cmd, app.getValue(), appString)); } /** * * * @param cmd * @param textField * @param applicationName * @return */ private EventHandler<ActionEvent> addDefaultAppEventHandler(ConfigString cmd, TextField textField, String applicationName) { EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { String text = textField.getText().trim(); feedbackMessage.setTextFill(Color.DARKRED); if (!text.isEmpty()) { if (!text.contains("{0}")) { feedbackMessage.setText(g.getText("SETTINGS.NOT_A_VALID_COMMAND", applicationName)); breakSaving = true; } } if (!breakSaving) { cfg.setProp(cmd, text); } } }; return handler; } /** * * */ private void addCustomDivider() { this.children.add(new Text("")); this.children.add(getCustomDivider()); this.children.add(new Text("")); } /** * * * @return */ private Line getCustomDivider() { return this.getDivider(SETTINGS_DIVIDER_CLASS, 2.0f, 50, 2d, 10d); } @Override protected void initListeners() { // TODO Auto-generated method stub } @Override protected void asserts() { // TODO Auto-generated method stub } @Override protected double getWindowWidth() { return INIT_WIDTH; } @Override protected double getWindowHeight() { return INIT_HEIGHT; } // ------------------------------------------------ // // -- // ------------------------------------------------ // /** * * * @param button */ private void updateToggleButtonText(ToggleButton button) { // button.setSelected(button.isSelected()); button.setText(button.isSelected() ? g.getText("YES") : g.getText("NO")); // TODO: style button.setTextFill(button.isSelected() ? Color.GREEN : Paint.valueOf("#4B0000")); } /** * * */ private void updateFields() { } /** * * * @param labelText * @param iconPath * @param growLabel * @param minWidth * @return */ private HBox createNewHbox(String labelText, String infoString, Icon iconPath, boolean growLabel, boolean boolButton, Double minWidth) { return createNewHbox(labelText, iconPath, growLabel, false, boolButton, minWidth, infoString); } /** * * * @param labelText * @param iconPath * @param growLabel * @param minWidth * @param infoText * @return */ private HBox createNewHbox(String labelText, Icon iconPath, boolean growLabel, boolean disabled, boolean boolButton, Double minWidth, String infoText) { HBox hbox = new HBox(); hbox.setSpacing(5); hbox.setAlignment(Pos.CENTER); HBox hboxLabel = new HBox(); if (growLabel) { HBox.setHgrow(hboxLabel, Priority.ALWAYS); } hboxLabel.setAlignment(Pos.CENTER_LEFT); if (infoText != null && minWidth != null) { minWidth -= 35; } Label label = new Label(); if (minWidth != null) { label.setMinWidth(minWidth); } label.setText(labelText); hboxLabel.getChildren().add(label); hbox.getChildren().add(hboxLabel); if (infoText != null) { ImageView infoIcon = new ImageView(this.getClass().getResource(Icon.INFO.getFileName()) .toString()); infoIcon.setCursor(Cursor.HAND); infoIcon.setFitHeight(30); infoIcon.setPickOnBounds(true); infoIcon.setPreserveRatio(true); infoIcon.setOnMouseClicked(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent t) { g.showConfirmationDialog(infoText, 400, 150); } }); hbox.getChildren().add(infoIcon); } if (iconPath != null) { String url = this.getClass().getResource(iconPath.getFileName()).toString(); ImageView icon = null; if (disabled) { // TODO: performance hit, replace with image file icon = new ImageView(this.getGreyscaleIcon(iconPath)); } else { icon = new ImageView(url); } icon.setFitHeight(30); // icon.setTranslateY(1); icon.setPickOnBounds(true); icon.setPreserveRatio(true); hbox.getChildren().add(icon); } return hbox; } /** * * * @param helpDisabled * @return */ private Button createHelpButton(final double translateY, final String anchorString) { Button help = new Button(); // TODO: style help.setMinWidth(40); help.setMaxWidth(40); help.setMinHeight(28); help.setMaxHeight(28); help.setTranslateY(translateY); this.addImageIcon(help, Icon.HELP, 1); if (anchorString != null) { EventHandler<ActionEvent> helpHandler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { String anchor = anchorString; anchor = anchor.replace("_" + Os.LINUX.name(), ""); anchor = anchor.replace("_" + Os.WINDOWS.name(), ""); anchor = anchor.replace("_" + Os.OSX.name(), ""); openHelpInBrowser(Config.getHelpFilePath(Localization.instance().getLocale()), anchor); } }; help.setOnAction(helpHandler); } else { help.setDisable(true); } return help; } /** * * * @param labelText * @param infoString * @param boolProperty * @param disabled * @param helpDisabled * @return */ private Tp<EventHandler<ActionEvent>, ToggleButton> addBooleanButton(String labelText, String infoString, ConfigBool boolProperty, boolean disabled, boolean helpDisabled) { return addBooleanButton(null, labelText, null, infoString, boolProperty, disabled, helpDisabled); } /** * * * @param labelText * @param iconPath * @param infoString * @param boolProperty * @param disabled * @param helpDisabled * @return */ private Tp<EventHandler<ActionEvent>, ToggleButton> addBooleanButton(String labelText, Icon iconPath, String infoString, ConfigBool boolProperty, boolean disabled, boolean helpDisabled) { return addBooleanButton(null, labelText, iconPath, infoString, boolProperty, disabled, helpDisabled); } /** * * * @param configFilePath * @param labelText * @param iconPath * @param infoString * @param boolProperty * @param disabled * @param helpDisabled * @return */ private void addToggleAllButton(String infoString, boolean helpDisabled) { HBox hbox = this.createNewHbox(g.getText("SETTINGS.TOGGLE_FILETYPES"), null, true, false, true, null, infoString); Button toggleButton = new Button(); toggleButton.setMinWidth(75); // TODO: style toggleButton.setStyle("-fx-font-size:16px;"); toggleButton.setText("\u2193\u2193\u2193"); EventHandler<ActionEvent> updateLabelHandler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { for (ToggleButton button : fileTypeButtons) { button.fire(); button.setSelected(!fileButtonsToggled); updateToggleButtonText(button); } fileButtonsToggled = !fileButtonsToggled; } }; toggleButton.setOnAction(updateLabelHandler); hbox.getChildren().add(toggleButton); hbox.getChildren().add(createHelpButton(0, helpDisabled == true ? null : "TOGGLE_ALL_BUTTON")); children.add(hbox); } /** * * * @param labelText * @param buttonText * @param iconPath * @param eventHandler */ private Tp<EventHandler<ActionEvent>, ToggleButton> addBooleanButton(String configFilePath, String labelText, Icon iconPath, String infoString, ConfigBool boolProperty, boolean disabled, boolean helpDisabled) { HBox hbox = this.createNewHbox(labelText, iconPath, true, disabled, true, null, infoString); ToggleButton toggleButton = new ToggleButton(); toggleButton.setDisable(disabled); toggleButton.setMinWidth(75); boolean toggleButtonStatus = false; if (configFilePath == null) { toggleButtonStatus = config.getProp(boolProperty); } else { toggleButtonStatus = config.getProp(configFilePath, boolProperty); } toggleButton.setSelected(toggleButtonStatus); updateToggleButtonText(toggleButton); EventHandler<ActionEvent> updateLabelHandler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { updateToggleButtonText(toggleButton); } }; EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { if (configFilePath == null) { config.setProp(boolProperty, toggleButton.isSelected()); } else { config.setProp(configFilePath, boolProperty, toggleButton.isSelected()); } } }; toggleButton.setOnAction(updateLabelHandler); this.updateToggleButtonText(toggleButton); hbox.getChildren().add(toggleButton); hbox.getChildren().add(createHelpButton(0, helpDisabled == true ? null : boolProperty.name())); children.add(hbox); this.saveHandlers.add(handler); return new Tp<EventHandler<ActionEvent>, ToggleButton>(handler, toggleButton); } // ------------------------------------------------ // // -- // ------------------------------------------------ // /** * * * @param labelText * @param iconPath * @param boolProperty * @param helpText * @return */ private EventHandler<ActionEvent> addDropdownMenu(String configFilePath, String infoString, String labelText, ConfigInteger integerProperty, Integer[] possibleValues, double width, boolean helpDisabled) { HBox hbox = this.createNewHbox(labelText, infoString, null, true, false, null); ComboBox<Integer> dropdown = new ComboBox<Integer>(); dropdown.setMinHeight(29); dropdown.setMaxHeight(29); dropdown.setPrefWidth(width); for (int i : possibleValues) { dropdown.getItems().add(i); } Integer loadedValue = null; if (configFilePath != null) { loadedValue = config.getProp(configFilePath, integerProperty); } else { loadedValue = config.getProp(integerProperty); } EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { if (configFilePath != null) { config.setProp(configFilePath, integerProperty, (Integer) dropdown.getSelectionModel() .getSelectedItem()); } else { config.setProp(integerProperty, (Integer) dropdown.getSelectionModel().getSelectedItem()); } } }; if (loadedValue != -1) { dropdown.getSelectionModel().select(loadedValue); } hbox.getChildren().add(dropdown); hbox.getChildren().add( createHelpButton(0, helpDisabled == true ? null : integerProperty.name())); children.add(hbox); return handler; } // ------------------------------------------------ // // -- // ------------------------------------------------ // /** * * * @param labelText * @param iconPath * @param boolProperty * @param helpDisabled * @return */ private EventHandler<ActionEvent> addDropdownMenu(String configFilePath, String labelText, String infoString, ConfigString stringProperty, String[] possibleValues, double width, boolean helpDisabled) { HBox hbox = this.createNewHbox(labelText, infoString, null, true, false, null); ComboBox<String> dropdown = new ComboBox<String>(); dropdown.setMinWidth(width); dropdown.setMaxWidth(width); dropdown.setMinHeight(29); dropdown.setMaxHeight(29); for (String st : possibleValues) { if (stringProperty == ConfigString.DEFAULT_LOCALE) { dropdown.getItems().add(st.split("-")[1]); } else { dropdown.getItems().add(st); } } String loadedValue = null; if (configFilePath != null) { loadedValue = config.getProp(configFilePath, stringProperty); } else { loadedValue = config.getProp(stringProperty); } if (stringProperty == ConfigString.DEFAULT_LOCALE) { final BidiMap<String, String> langs = this.cfg.getGUILanguageStrings(); if (langs.containsKey(loadedValue)) { loadedValue = langs.get(loadedValue).trim(); } } if (!loadedValue.isEmpty()) { dropdown.getSelectionModel().select(loadedValue); } EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { String selectedItem = ((String) dropdown.getSelectionModel().getSelectedItem()).split("-")[0] .trim(); if (stringProperty == ConfigString.DEFAULT_LOCALE) { final BidiMap<String, String> langs = cfg.getGUILanguageStrings(); if (langs.containsValue(selectedItem)) { selectedItem = langs.getKey(selectedItem); Localization.instance().setLocale(LocaleUtils.toLocale(selectedItem)); } } if (configFilePath != null) { cfg.setProp(configFilePath, stringProperty, selectedItem); } else { cfg.setProp(stringProperty, selectedItem); } } }; hbox.getChildren().add(dropdown); hbox.getChildren() .add(createHelpButton(0, helpDisabled == true ? null : stringProperty.name())); children.add(hbox); return handler; } /** * * * @param labelText * @param buttonText * @param iconPath * @param eventHandler */ private Tp<EventHandler<ActionEvent>, TextField> addStringField(String labelText, String infoString, ConfigString stringProperty, boolean helpDisabled) { HBox hbox = this.createNewHbox(labelText, infoString, null, false, false, 120d); HBox textBox = new HBox(); // textBox.setAlignment(Pos.CENTER_RIGHT); TextField textfield = new TextField(); textfield.setMinHeight(29); textfield.setMaxHeight(29); String loadedText = config.getProp(stringProperty); if (!loadedText.isEmpty()) { textfield.setText(loadedText); } textBox.setPadding(new Insets(0, 0, 0, 10)); HBox.setHgrow(textBox, Priority.ALWAYS); HBox.setHgrow(textfield, Priority.ALWAYS); textBox.getChildren().add(textfield); hbox.getChildren().add(textBox); hbox.getChildren() .add(createHelpButton(0, helpDisabled == true ? null : stringProperty.name())); children.add(hbox); EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { String text = textfield.getText().trim(); if (!text.isEmpty()) { cfg.setProp(stringProperty, text); } } }; this.saveHandlers.add(handler); return new Tp<EventHandler<ActionEvent>, TextField>(handler, textfield); } /** * * * @param integerProperty * @param infoString * @param labelText * @param integerName * @param helpDisabled * @param unit * @return */ private Tp<EventHandler<ActionEvent>, TextField> addIntegerField(ConfigInteger integerProperty, String infoString, String labelText, String integerName, boolean helpDisabled, String unit) { return addIntegerField(integerProperty, infoString, labelText, integerName, helpDisabled, unit, 75); } /** * * * @param labelText * @param integerProperty * @param width * @param helpDisabled * @return */ private Tp<EventHandler<ActionEvent>, TextField> addIntegerField(ConfigInteger integerProperty, String infoString, String labelText, String integerName, boolean helpDisabled, String unit, double width) { HBox hbox = this.createNewHbox(labelText, infoString, null, true, false, null); // textBox.setAlignment(Pos.CENTER_RIGHT); TextField textfield = new TextField(); textfield.setMinHeight(29); textfield.setMaxHeight(29); textfield.setMinWidth(width); textfield.setMaxWidth(width); int loadedInteger = config.getProp(integerProperty); if (loadedInteger != -1) { textfield.setText(String.valueOf(loadedInteger) + " " + unit); } HBox.setHgrow(textfield, Priority.ALWAYS); hbox.getChildren().add(textfield); hbox.getChildren().add( createHelpButton(0, helpDisabled == true ? null : integerProperty.name())); children.add(hbox); EventHandler<ActionEvent> handler = getDefaultIntegerEventHandler(integerProperty, textfield, integerName, unit); this.saveHandlers.add(handler); return new Tp<EventHandler<ActionEvent>, TextField>(handler, textfield); } /** * * * @param property * @param textField * @param integerProp * @return */ private EventHandler<ActionEvent> getDefaultIntegerEventHandler(ConfigInteger property, TextField textField, String integerProp, String unit) { EventHandler<ActionEvent> handler = new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { String text = textField.getText().trim(); feedbackMessage.setTextFill(Color.DARKRED); if (text.isEmpty()) { feedbackMessage.setText(g.getText("SETTINGS.STRING_EMPTY", integerProp)); breakSaving = true; } else { Integer value = St.extractInteger(text); if (value != null) { cfg.setProp(property, value); } else { feedbackMessage.setText(g.getText("SETTINGS.NOT_A_NUMBER", integerProp)); breakSaving = true; } } } }; return handler; } /** * * * @return */ public Task<Object> saveWorker() { return new Task<Object>() { @Override protected Object call() throws Exception { try { Thread.sleep(breakSaving ? 5000 : 500); } catch (InterruptedException e) { e.printStackTrace(); } Platform.runLater(new Runnable() { @Override public void run() { if (breakSaving) { feedbackMessage.setText(g.getText("SETTINGS.SAVE_REMINDER")); final ObservableList<String> styleClasses = feedbackMessage.getStyleClass(); styleClasses.clear(); styleClasses.add(SETTINGS_BUTTON_DEFAULT_CLASS); } else { gotoPage(EditDatabase.FXML, EditDatabase.INIT_WIDTH, EditDatabase.INIT_HEIGHT); } } }); return true; } }; } @Override protected void initEventHandlers() { this.pane.getScene().addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { if ((event.isShiftDown() && (event.getCode() == KeyCode.J || event.getCode() == KeyCode.DOWN))) { settingsScrollPane.setVvalue(settingsScrollPane.getVvalue() + 0.05); } else if (event.isShiftDown() && (event.getCode() == KeyCode.K || event.getCode() == KeyCode.UP)) { settingsScrollPane.setVvalue(settingsScrollPane.getVvalue() - 0.05); } else if (event.getCode() == KeyCode.J || event.getCode() == KeyCode.DOWN) { settingsScrollPane.setVvalue(settingsScrollPane.getVvalue() + 0.005); } else if (event.getCode() == KeyCode.K || event.getCode() == KeyCode.UP) { settingsScrollPane.setVvalue(settingsScrollPane.getVvalue() - 0.005); } } }); } }